package com.item.manager;

import org.immutables.value.Value;

import java.util.LinkedList;
import java.util.Optional;
import java.util.Set;

import static com.item.manager.MixinPosition.SUFFIX;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toSet;
import static org.immutables.value.internal.google.common.collect.Sets.newHashSet;

/**
 * Main item template.
 *
 * Created by Alexey on 2/27/2015.
 */
@Value.Immutable
public interface Template extends Tagged {
    String name();
    Set<Attribute> attributes();
    Set<MixinTemplate> mixin();

    default Attribute findAttr(String name) {
        return attributes().stream().filter(a -> a.name().equals(name)).findAny().get();
    }

    default Set<Attribute> findAttrSet(String name) {
        return attributes().stream().filter(a -> a.name().equals(name)).collect(toSet());
    }

    default Optional<Attribute> tryByName(String name) {
        return attributes().stream().filter(a -> a.name().equals(name)).findAny();
    }

    @Value.Lazy
    default Set<Tag> allTags() {
        Set<Tag> tagged = newHashSet(this.tags());
        tagged.addAll(attributes().stream().flatMap((Tagged a) -> a.tags().stream()).collect(toSet()));
        tagged.addAll(mixin().stream().flatMap(a -> a.allTags().stream()).collect(toSet()));
        return tagged;
    }

    @Value.Lazy
    default String flavor() {
        LinkedList<String> flavors = new LinkedList<>(asList(name()));
        mixin().forEach(m -> {
            if (m.position() == SUFFIX) {
                flavors.addFirst(m.flavor());
            } else {
                flavors.addLast(m.flavor());
            }
        });
        return flavors.stream().reduce((s1, s2) -> s1 + " " + s2).orElse("");
    }

}
